package com.dkakunsi.monev.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.dkakunsi.monev.util.MonevDataException;

public abstract class GenericDao<T> {
	protected Class<T> domainClass;
	@Autowired protected SessionFactory sessionFactory;

	@SuppressWarnings("unchecked")
	public GenericDao() {
		this.domainClass = (Class<T>)((ParameterizedType)
                getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
	}

	public Session getSession() {
		Session session = null;
		try {
			session = sessionFactory.getCurrentSession();
			if(!session.isOpen()) {
				session = sessionFactory.openSession();
			}
		} catch(HibernateException e) {
			session = sessionFactory.openSession();
		}
		return session;
	}

	
	public void save(T t) {
		getSession().saveOrUpdate(t);
	}
	
	public void delete(T t) {
		getSession().delete(t);
	}
	
	@SuppressWarnings("unchecked")
	public T get(Object obj) throws MonevDataException {
		return checkNull((T)getSession().get(domainClass, (Serializable)obj));
	}
	
	@SuppressWarnings("unchecked")
	public List<T> getAll() throws MonevDataException {
		Query query = getSession().createQuery("SELECT i FROM " + domainClass.getSimpleName() + " i");
		
		return checkNull(query.list());
	}

	protected T checkNull(T entity) throws MonevDataException {
		if(entity == null)
			throw new MonevDataException("Entitas '" + domainClass.getSimpleName() + "' tidak ditemukan di dalam basis data");
		return entity;
	}
	
	protected List<T> checkNull(List<T> ls) throws MonevDataException {
		if((ls == null))
			throw new MonevDataException("Entitas '" + domainClass.getSimpleName() + "' tidak ditemukan di dalam basis data");
		if(ls.size() <= 0)
			throw new MonevDataException("Entitas '" + domainClass.getSimpleName() + "' tidak ditemukan di dalam basis data");
		return ls;
	}
}
